package com.maiji.cloud.aop;

import com.alibaba.fastjson.JSON;
import com.maiji.cloud.response.BaseDataResDto;
import com.maiji.cloud.response.BaseMetaResDto;
import com.maiji.cloud.response.BaseOutPutDto;
import com.maiji.cloud.response.community.ComDetailOutputDto;
import com.maiji.cloud.response.community.ComRecsOutputDto;
import com.maiji.cloud.response.login.RecipeResData;
import com.maiji.cloud.response.shopingmall.GoodsResData;
import com.maiji.cloud.response.shopingmall.ShopingOrderResData;
import com.maiji.cloud.utils.ShareInfoEnum;
import com.maiji.cloud.utils.UUID_MD5;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;

@Component
@Aspect
public class WebControllerAop {

    Logger logger = LoggerFactory.getLogger(WebControllerAop.class);
    @Value("${realmName}")
    private String realmName;

    @Pointcut("execution(* com.maiji.cloud.controller.*.*.*(..))")
    public  void executeService(){}

    @AfterReturning(value="executeService()", returning = "baseDataResDto")
    public <T> void doAfterReturningGoodsResDatas(BaseMetaResDto<List<GoodsResData>> baseDataResDto){
        dealWithList(baseDataResDto.getData(), GoodsResData.class);
    }

    @AfterReturning(value="executeService()", returning = "baseDataResDto")
    public <T> void doAfterReturningGoodsResData(BaseDataResDto<GoodsResData> baseDataResDto){
        dealWithList(Arrays.asList((Object) baseDataResDto.getData()), GoodsResData.class);
    }

    @AfterReturning(value="executeService()", returning = "baseDataResDto")
    public <T> void doAfterReturningShopingOrderResDatas(BaseMetaResDto<List<ShopingOrderResData>> baseDataResDto){
        dealWithList(baseDataResDto.getData(), ShopingOrderResData.class);
    }

    @AfterReturning(value="executeService()", returning = "baseDataResDto")
    public <T> void doAfterReturningShopingOrderResData(BaseDataResDto<ShopingOrderResData> baseDataResDto){
        dealWithList(Arrays.asList((Object) baseDataResDto.getData()), ShopingOrderResData.class);
    }

    @AfterReturning(value="executeService()", returning = "baseDataResDto")
    public <T> void doAfterReturningRecipeResDatas(BaseMetaResDto<List<RecipeResData>> baseDataResDto){
        dealWithList(baseDataResDto.getData(), RecipeResData.class);
    }

    @AfterReturning(value="executeService()", returning = "baseDataResDto")
    public <T> void doAfterReturningRecipeResData(BaseDataResDto<RecipeResData> baseDataResDto){
        dealWithList(Arrays.asList((Object) baseDataResDto.getData()), RecipeResData.class);
    }

    @AfterReturning(value = "executeService()",returning = "baseOutPutDto")
    public <T> void doAfterReturningComRecses(BaseOutPutDto<List<ComRecsOutputDto>> baseOutPutDto){
        dealWithList(baseOutPutDto.getData(),ComRecsOutputDto.class);
    }

    @AfterReturning(value = "executeService()",returning = "baseOutPutDto")
    public <T> void doAfterReturningComDetail(BaseOutPutDto<ComDetailOutputDto> baseOutPutDto){
        Object bean = baseOutPutDto.getData();
        if(bean != null){
            LinkedHashMap map = (LinkedHashMap) bean;
            dealWithList(Arrays.asList((Object) map.get("detailMsg") ) ,ComRecsOutputDto.class);
        }
    }

    private void dealWithList (List list, Class clazz) {
        if (list == null || list.size() == 0) return;
        list.parallelStream().forEach(bean -> {
            if (bean != null) {
                LinkedHashMap map = (LinkedHashMap) bean;
                String uuId = (String) map.get("uuId");
                if (clazz == GoodsResData.class) {
                    map.put("webUrl", realmName + ShareInfoEnum.SHARE_GOODS.getWebUrl() + uuId);
                    map.put("shareUrl", realmName + ShareInfoEnum.SHARE_GOODS.getShareUrl() + uuId);
                    if ((Integer) map.get("isExchange") == 1) {
                        map.put("webUrl2", realmName + ShareInfoEnum.SHARE_GOODS.getWebUrl2() + uuId);
                        map.put("shareUrl2", realmName + ShareInfoEnum.SHARE_GOODS.getShareUrl2() + uuId);
                    }
                }
                else if (clazz == ShopingOrderResData.class) {
                    map.put("resultUrl", realmName + "/pages/orderPay/orderPay?uuId=" + uuId);
                }
                else if (clazz == RecipeResData.class) {
                    map.put("webUrl", realmName + ShareInfoEnum.SHARE_RECIPE.getWebUrl() + uuId);
                    map.put("shareUrl", realmName + ShareInfoEnum.SHARE_RECIPE.getShareUrl() + uuId);
                }
                else if(clazz == ComRecsOutputDto.class){
                    LinkedHashMap msg = (LinkedHashMap) map.get("msg");
                    String msgId = (String)msg.get("msgId");
                    msg.put("shareUrl",realmName + ShareInfoEnum.SHARE_COMMUNITY.getShareUrl() + msgId);
                    msg.put("webUrl", realmName + ShareInfoEnum.SHARE_COMMUNITY.getWebUrl() + msgId);
                }
            }
        });
    }

    /*@Around("execution(* com.maiji.cloud.controller..*(..))")
    public Object doAroundService(ProceedingJoinPoint proceedingJoinPoint){
        String requestId = UUID_MD5.getUUID();
        try {
            Object[] args = proceedingJoinPoint.getArgs();
            logger.info("doAroundService: " + requestId + " ===>> "+proceedingJoinPoint.getSignature().getName() + ": args ===>> " + JSON.toJSONString(args));
            Object object=proceedingJoinPoint.proceed();
            logger.info("doAroundService: " + requestId + " ===>> "+proceedingJoinPoint.getSignature().getName() + ": return ===>> " + JSON.toJSONString(object));
            return object;
        } catch (Throwable throwable) {
            logger.info("doAroundService: " + requestId + " ===>> "+proceedingJoinPoint.getSignature().getName() + ": throwable");
            throwable.printStackTrace();
        }
        return null;
    }*/

}
